layui.define('layer', function(exports){
  "use strict";  
    var MOD_NAME = 'selectTree';
    
    // 生成html
    var getHtml = function(data,config){   
        var showValue = '';
        var eachData = function(dlist,depth){
            var temp = '';
            $.each(dlist,function(key,val){
                 var thisCss = '';
                 var showdepth = depth;
                 if( val[config.field.id] == config.checkid ){
                    thisCss =  'layui-this';
                    showValue = val[config.field.name];
                 }
                 if( showdepth == 1 && val.depth > 1 ) showdepth = val.depth; 
                 temp += '<dd lay-value="'+val[config.field.id]+'" class="'+thisCss+ ' e-select-depth'+showdepth+'">'+val[config.field.name]+'</dd>';  
                 if( depth < config.maxdepth && typeof val[config.field.child] == 'object' && typeof val[config.field.child][0] != 'undefined' ){
                    temp += eachData(val[config.field.child] , depth + 1);
                 }                 
            });
            return temp;
        }        
        var htmlDl = eachData(data,1);
        var id = config.box.substring(1);
        var html = '<div class="layui-form-select" id="'+id+'">'
                   +'     <div class="layui-select-title">'
                   +'         <input class="saveval" type="hidden" name="'+config.name+'" value="'+config.checkid+'">'
                   +'         <input type="text" placeholder="'+config.placeholder+'" value="'+showValue+'" class="layui-input">'
                   +'         <i class="layui-edge"></i>'
                   +'     </div>'                                
                   +'     <dl class="layui-anim layui-anim-upbit">'
                   +'         <dd lay-value="" class="layui-select-tips e-select-depth">'+config.placeholder+'</dd>'
                   + htmlDl
                   +'     </dl>'
                   +' </div>';
        return html;
    }
    
    // 各种事件操作处理
    var events = function(EThis,reElem,isSearch){        
        var TIPS = '请选择', CLASS = 'layui-form-select', TITLE = 'layui-select-title',NONE = 'layui-select-none',  HIDE = 'layui-hide', THIS = 'layui-this' ,SHOW = 'layui-show', DISABLED = 'layui-disabled',thatInput,initValue = '';  
        
        var title = reElem.find('.' + TITLE),
            input = title.find('input.layui-input'),    // 页面展示的input
            formInput = title.find('input.saveval'),    //提交表单保存的input
            dl = reElem.find('dl'),
            dds = dl.children('dd'),
           // index =  this.selectedIndex, //当前选中的索引
            nearElem; //select 组件当前选中的附近元素，用于辅助快捷键功能    
          
        var hide = function(e, clear){
            if(!$(e.target).parent().hasClass(TITLE) || clear){
                $('.'+CLASS).removeClass(CLASS+'ed ' + CLASS+'up');
                thatInput && initValue && thatInput.val(initValue);
            }
            thatInput = null;
        }                
        
        //展开下拉
        var showDown = function(){                
            reElem.addClass(CLASS+'ed');
            dds.removeClass(HIDE);
            nearElem = null;                 
            var top = reElem.offset().top - $win.scrollTop();   
            var maxHight = ($win.height()-40)/2;
            if(top > maxHight ){
                reElem.addClass(CLASS + 'up');
            }   
            if( maxHight < 300 ){
                maxHight = maxHight > top ? maxHight : ( top > 300 ? 300 : top - 20 );
                dl.css({'max-height': maxHight+'px'});
            }             
            followScroll();
        },
        //隐藏下拉
        hideDown = function(choose){
            reElem.removeClass(CLASS+'ed ' + CLASS+'up');
            input.blur();
            nearElem = null;            
            if(choose) return;                
            notOption(input.val(), function(none){
                // TODO
            });
        },
        
        //定位下拉滚动条
        followScroll = function(){  
            var thisDd = dl.children('dd.'+ THIS); 
            if( thisDd.html() == undefined ) return true;
            var posTop = thisDd.position().top,
            dlHeight = dl.height(),
            ddHeight = thisDd.height();  
            //若选中元素在滚动条不可见底部
            if(posTop > dlHeight){
                dl.scrollTop(posTop + dl.scrollTop() - dlHeight + ddHeight - 5);
            }                
            //若选择元素在滚动条不可见顶部
            if(posTop < 0){
                dl.scrollTop(posTop + dl.scrollTop() - 5);
            }
            
        };
        
        //点击标题区域
        title.on('click', function(e){
            reElem.hasClass(CLASS+'ed') ? (hideDown()) : ( hide(e, true), showDown() );
            dl.find('.'+NONE).remove();
        });
        //点击箭头获取焦点
        title.find('.layui-edge').on('click', function(){
            input.focus();
        });
        
        //select 中 input 键盘事件
        input.on('keyup', function(e){ //键盘松开
            var keyCode = e.keyCode;                
            //Tab键展开
            if(keyCode === 9){
                showDown();
            }
        }).on('keydown', function(e){ //键盘按下
            var keyCode = e.keyCode;
        
            //Tab键隐藏
            if(keyCode === 9){
                hideDown();
            }
        
            //标注 dd 的选中状态
            var setThisDd = function(prevNext, thisElem1){
                var nearDd, cacheNearElem
                e.preventDefault();
                
                //得到当前队列元素  
                var thisElem = function(){
                    var thisDd = dl.children('dd.'+ THIS);
                    
                    //如果是搜索状态，且按 Down 键，且当前可视 dd 元素在选中元素之前，
                    //则将当前可视 dd 元素的上一个元素作为虚拟的当前选中元素，以保证递归不中断
                    if(dl.children('dd.'+  HIDE)[0] && prevNext === 'next'){
                        var showDd = dl.children('dd:not(.'+ HIDE +',.'+ DISABLED +')'),
                        firstIndex = showDd.eq(0).index();
                        //if(firstIndex >=0 && firstIndex < thisDd.index() && !showDd.hasClass(THIS)){
                        if(firstIndex >=0 && !showDd.hasClass(THIS)){
                            return showDd.eq(0).prev()[0] ? showDd.eq(0).prev() : dl.children(':last');
                        }
                    }
                    
                    if(thisElem1 && thisElem1[0]){
                        return thisElem1;
                    }
                    if(nearElem && nearElem[0]){
                        return nearElem;
                    }
                    
                    return thisDd;
                    //return dds.eq(index);
                }();            
                cacheNearElem = thisElem[prevNext](); //当前元素的附近元素
                nearDd =  thisElem[prevNext]('dd:not(.'+ HIDE +')'); //当前可视元素的 dd 元素
                                
                //如果附近的元素不存在，则停止执行，并清空 nearElem
                if(!cacheNearElem[0]) return nearElem = null;
                
                //记录附近的元素，让其成为下一个当前元素
                nearElem = thisElem[prevNext]();
                
                //如果附近不是 dd ，或者附近的 dd 元素是禁用状态，则进入递归查找
                if((!nearDd[0] || nearDd.hasClass(DISABLED)) && nearElem[0]){
                    return setThisDd(prevNext, nearElem);
                }
                
                nearDd.addClass(THIS).siblings().removeClass(THIS); //标注样式
                followScroll(); //定位滚动条
            };
        
            if(keyCode === 38) setThisDd('prev'); //Up 键
            if(keyCode === 40) setThisDd('next'); //Down 键
            
            //Enter 键
            if(keyCode === 13){ 
                e.preventDefault();
                dl.children('dd.'+THIS).trigger('click');
            }
        });
        
        //检测值是否不属于 select 项
        var notOption = function(value, callback, origin){
            var num = 0;
            layui.each(dds, function(){
                var othis = $(this),
                text = othis.text(),
                not = text.indexOf(value) === -1;
                if(value === '' || (origin === 'blur') ? value !== text : not) num++;
                origin === 'keyup' && othis[not ? 'addClass' : 'removeClass'](HIDE);
            });
            var none = num === dds.length;
            return callback(none), none;
        };
        
        //搜索匹配
        var search = function(e){
            var value = this.value, keyCode = e.keyCode;  
            if(keyCode === 9 || keyCode === 13 
                || keyCode === 37 || keyCode === 38 
                || keyCode === 39 || keyCode === 40
                ){
                return false;
            }
            
            notOption(value, function(none){
                if(none){
                    dl.find('.'+NONE)[0] || dl.append('<p class="'+ NONE +'">无匹配项</p>');
                } else {
                    dl.find('.'+NONE).remove();
                }
            }, 'keyup');
            
            if(value === ''){
                dl.find('.'+NONE).remove();
            }                
            followScroll(); //定位滚动条
        };
        
        if(isSearch){
            input.on('keyup', search).on('blur', function(e){
                thatInput = input; //当前的 select 中的 input 元素
                initValue = dl.find('.'+THIS).text(); //重新获得初始选中值
                //console.log(initValue);
            });
        }        
        //选择
        dds.on('click', function(){
            var othis = $(this), value = othis.attr('lay-value');
            if(othis.hasClass(DISABLED)) return false;            
            if(othis.hasClass('layui-select-tips')){
                input.val('');
                formInput.val('');
            } else {
                input.val(othis.text());
                formInput.val(value);
                othis.addClass(THIS);
            }            
            othis.siblings().removeClass(THIS);
            hideDown(true);
            if( typeof EThis.config.done == 'function' ){
                EThis.config.done({ id:value,name:othis.text()} );
            } 
            return false;
        });
        
        reElem.find('dl>dt').on('click', function(e){
            return false;
        });          
        $(document).off('click', hide).on('click', hide); //点击其它元素关闭 select 
    }
    
    
    var select = function (options){
        var that = this;
        that.config = {
            placeholder : '请选择',            
            elem : '#JS_select', //绑定的容器元素
          //  box  : '#JS_select_TreeBox', // 内部ID
            url  : '', //获取数据的接口
            data : {}, //展示的数据 和 url 赋值其中一个 data 优先 没有的话从接口获取数据
            checkid : '', // 数据选中的ID
            name : 'group', // 生成的表单名称
            maxdepth : 9,   // 展示数据最多多少层级
            done : function(val){},  // 成功选择之后的回调
            field : {
                id      : 'id',     // 上传表单的值对应的字段
                name    : 'name',   // 显示的名称
                depth   : 'depth',   // 级别字段
                child   : 'child',   // 子集字段标识
            }
        }
        $.extend(true,that.config, options);
        //console.log(that.config);
        that.config.box = that.config.elem+'-0TreeBox';        
        $(that.config.elem).find(that.config.box).remove(); //删掉重复的
        var reElem = $( getHtml(options.data,that.config) );
        $(that.config.elem).prepend(reElem);        
        events(that, reElem, true); 
    }
    
    var selectTree = {        
        render:function(options){
            return new select(options);           
        }
    }
    var $dom = $(document), $win = $(window);
    exports(MOD_NAME, selectTree);
});